#ifndef __COMMON_H__
#define __COMMON_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "testack.h"
#include "tgc.h"
#include <iostream>

#ifdef _MSC_VER

#define bool int
#define true 1
#define false 0
typedef int intptr_t;

#else

#include <stdbool.h>
#include <stdint.h>

#endif

#define my_malloc malloc
#define my_free free
#define my_realloc realloc

#define CACHE_BITS 10

struct link {
	int number;
	int children[1];
};

struct node {
	int mark;
	union {
		struct {
			void * mem;
			struct link *children;
			void (*finalizer)(void *);
		} n;
		struct {
			intptr_t mem;
			struct link *children;
			intptr_t weak;
		} c;
		int free;
	} u;
};

/*	   stack data
	  +----------+
	0 | level 0  |                ----> level 0 / root ( node pack )
	1 | level 1  |                --+-> level 1 ( 1 node ref + node pack )
	2 | node ref | <-bottom       --+
	3 | 2 (lv.2) |
	4 | node ref |                --+-> level 2 ( 3 node ref )
	5 | node ref |                  |
	6 | node ref |                --+
	7 | 4 (lv.3) | <-current
	8 | node ref |                --+-> level 3 ( 2 node ref )
	9 | node ref |                --+
	10|   nil    | <-top
	11|   nil    |
	  +----------+
 */

union stack_node {
	int stack;
	int number;
	int handle;
};

struct stack {
	union stack_node *data;
	int top;
	int bottom;
	int current;
};

struct hash_node {
	int id;
	struct hash_node *next;
};

struct hash_map	{
	struct hash_node **table;
	int size;
	struct hash_node *free;
	int number;
};

#define	CACHE_SIZE (1<<CACHE_BITS)

struct cache_node {
	int parent;
	int child;
};

static struct {
	struct node *pool;
	int size;
	int free;
	int mark;
	bool cache_dirty;
	struct stack stack;
	struct hash_map map;
	struct cache_node cache[CACHE_SIZE];
} E;

#define WEAK_CONTAINER -1
#define FREED_POINTER -1
#define CACHE_PARENT_BITS (CACHE_BITS/3)
#define CACHE_CHILD_BITS (CACHE_BITS-CACHE_PARENT_BITS)
#define CACHE_PARENT_MASK ((1<<CACHE_PARENT_BITS) -1 )
#define CACHE_CHILD_MASK ((1<<CACHE_CHILD_BITS) -1 )
#define UNSET_MASK 0x80000000
#define UNSET_MASK_BIT(a) ((unsigned)(a)>>31)


/* Insert a parent/child handle pair into cache	*/
#endif